﻿using commonImportPlugin.Configs.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace commonImportPlugin.Configs.PbocFile
{
    /// <summary>
    /// 普通模式金融处理配置类
    /// </summary>
    public class PbocFileConfig : ConfigsBase,IcommonBase
    {
        //
        //    基本配置参数
        //
        #region
        /// <summary>
        /// 工厂配置
        /// </summary>
        public string factory { set; get; }
        /// <summary>
        /// 筛选数据文件规则
        /// (文件名正则[#]文件内容正则)
        /// </summary> 
        public string fileFilterRules { set; get; }
        /// <summary>
        /// 金融数据长度表示是否逆序(1逆序；0不逆序)
        /// </summary>
        public int isRevers { set; get; }
        /// <summary>
        ///一个金融文件的数据量
        /// P_getRecordCountConstantValue=0; 如下3参数才生效
        ///P_getRecordCountConstantValue>=1;表示直接给固定值
        ///P_getRecordCountConstantValue=-1;数据无给出记录数
        /// </summary>
        public int getRecordCountConstantValue { set; get; }    
       /// <summary>
        /// 截取开头多少字节用于匹配
        /// </summary>
        public int getRecordCountSpaceSize { set; get; }
        /// <summary>
        /// 获取记录数的正则表达式
        /// </summary>
        public string getRecordCountRegex { set; get; }
        /// <summary>
        /// 获取记录数的规则
        /// </summary>
        public string getRecordLength { set; get; }
        /// <summary>
        /// 设置文件流位置的正则表达式
        /// </summary>
        public string setPositionRegex { set; get; }
        /// <summary>
        /// 截取开头多少字节用于正则匹配
        /// </summary>
        public int setPositionSpaceSize { set; get; }
        /// <summary>
        /// 设置固定值
        /// </summary>
        public int setPositionConstantValue { set; get; }
        /// <summary>
        /// 指针位置调整
        /// </summary>
        public int setPositionStepAdjust { set; get; }
        /// <summary>
        /// ic 数据的格式(0为机器码格式,1为转码后格式)
        /// </summary>
        public int icDataFormat { set; get; }

        /// <summary>
        /// 获取IC数据的规则
        /// </summary>
        public string[] icRules { set; get; }

        /// <summary>
        /// 磁条数据在数据中的格式
        /// </summary>
        public int trackFormat { set; get; }

        /// <summary>
        /// 磁条数据分隔符
        /// </summary>
        public string[] trackSeparators { set; get; }
        /// <summary>
        /// 获取磁条的规则
        /// </summary>
        public string[] trackRules { set; get; }
        /// <summary>
        /// 5A在数据中的格式
        /// </summary>
        public int fiveAFormat { set; get; }
        /// <summary>
        /// 获取5A的规则
        /// </summary>
        public string[] fiveARules { set; get; }
        /// <summary>
        /// 银行卡号在数据中的格式
        /// </summary>
        public int bankCardIdFormat { set; get; }
        /// <summary>
        /// 获取银行卡号规则
        /// </summary>
        public string[] bankCardIdRules { set; get; }
        /// <summary>
        /// 身份证号的格式
        /// </summary>
        public int personIdFormat { set; get; }
        /// <summary>
        /// 获取身份证号的规则
        /// </summary>
        public string[] personIdRules { set; get; }
        /// <summary>
        /// 检查ic数据的正则表达式
        /// </summary>
        public string icDataCheckRegex { set; get; }
        /// <summary>
        /// 磁条数据检查正则
        /// </summary>
        public string trackDataCheckRegex { set; get; }
        /// <summary>
        /// 检查银行卡号的正则表达
        /// </summary>
        public string bankCardIdCheckRegex { set; get; }
        /// <summary>
        /// 检查身份证号的正则
        /// </summary>
        public string personIdCheckRegex { set; get; }
        /// <summary>
        /// 该参数用于实现过滤之前已导入的数据
        /// 该参数为成功日志过滤项位（1开始)
        /// </summary>
        public string filterItem { set; get; }
        #endregion

        //
        //    其他
        //
        #region
        private static PbocFileConfig uniqueInstance;
        /// <summary>
        /// 初始化配置
        /// </summary>
        /// <param name="configs"></param>
        public void Init()
        {
            PbocFileConfig pbocFileConfig = new PbocFileConfig();
            //检查格式是否为：（非|）|数字（-+）|数字（-+）
            string checkRuleRegex = @"^[^\|]*\|((\d*|-\d+)|((\d+|-\d+),(\d+|-\d+)))\|((\d*|-\d+)|((\d+|-\d+),(\d+|-\d+)))$";

            //
            //////  基础配置  
            //
            #region
            //工厂配置
            pbocFileConfig.factory = configs["PbocFileFactory"];
   
            //文件扩展名
            if (!IsKeyExist("PbocFileFilterRules"))
                throw new Exception(PbocErrors.PbocFileFilterRulesError);

            pbocFileConfig.fileFilterRules = configs["PbocFileFilterRules"];

            //长度字段是否逆序
            if (IsKeyExist("PbocIsRevers"))
            {
                if (string.IsNullOrEmpty(configs["PbocIsRevers"]))
                    pbocFileConfig.isRevers = 0;
                else
                {
                    if (!Regex.IsMatch(configs["PbocIsRevers"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocIsReversError);
                    pbocFileConfig.isRevers = configs["PbocIsRevers"] == "1" ? 1 : 0;
                }
            }
            #endregion

            //
            //////  getRecordCount函数  
            //
            #region
            //记录数参数          
            if (IsKeyExist("PbocGetRecordCountConstantValue"))
            {
                if (!Regex.IsMatch(configs["PbocGetRecordCountConstantValue"], @"^(-\d+|\d+)$"))
                    throw new Exception(PbocErrors.PbocGetRecordCountConstantValueError);

                pbocFileConfig.getRecordCountConstantValue = int.Parse(configs["PbocGetRecordCountConstantValue"]);
            }

            //正则匹配开辟的空间数
            if (IsKeyExist("PbocGetRecordCountSpaceSize"))
            {
                if (!Regex.IsMatch(configs["PbocGetRecordCountSpaceSize"], @"^\d+$"))
                    throw new Exception(PbocErrors.PbocGetRecordCountSpaceSizeError);

                pbocFileConfig.getRecordCountSpaceSize = int.Parse(configs["PbocGetRecordCountSpaceSize"]);
            }

            //获取记录数的正则
            if (IsKeyExist("PbocGetRecordCountRegex"))
            {
                pbocFileConfig.getRecordCountRegex = configs["PbocGetRecordCountRegex"];
            }

            //表示记录数的长度字节
            if (IsKeyExist("PbocGetRecordLength"))
            {
                if (!Regex.IsMatch(configs["PbocGetRecordLength"], @"(^\d+$)|(^\d+,\d+$)"))
                    throw new Exception(PbocErrors.PbocGetRecordLengthError);

                pbocFileConfig.getRecordLength = configs["PbocGetRecordLength"];
            }
            #endregion

            //
            ///////  setPosition函数参数
            //
            #region
            //设置指针位置的参数
            if (IsKeyExist("PbocSetPositionConstantValue"))
            {
                if (!Regex.IsMatch(configs["PbocSetPositionConstantValue"], @"^(-\d+|\d+)$"))
                    throw new Exception(PbocErrors.PbocSetPositionConstantValueError);

                pbocFileConfig.setPositionConstantValue = int.Parse(configs["PbocSetPositionConstantValue"]);
            }

            //定位指针位置的正则
            if (IsKeyExist("PbocSetPositionRegex"))
            {
                pbocFileConfig.setPositionRegex = configs["PbocSetPositionRegex"];
            }

            //正则匹配开辟的空间数
            if (!IsKeyEmpty("PbocSetPositionSpaceSize"))
            {
                if (!Regex.IsMatch(configs["PbocSetPositionSpaceSize"], @"^\d+$"))
                    throw new Exception(PbocErrors.PbocSetPositionSpaceSizeError);

                pbocFileConfig.setPositionSpaceSize = int.Parse(configs["PbocSetPositionSpaceSize"]);
            }

            //定位指针位置调整参数
            if (!IsKeyEmpty("PbocSetPositionStepAdjust"))
            {
                if (!Regex.IsMatch(configs["PbocSetPositionStepAdjust"], @"^(-\d+|\d+)$"))
                    throw new Exception(PbocErrors.PbocSetPositionStepAdjustError);

                pbocFileConfig.setPositionStepAdjust = int.Parse(configs["PbocSetPositionStepAdjust"]);
            }
            #endregion

            //
            ////////  获取IC
            //
            #region
            //ic数据的格式：0表示机器码,1表示转换后
            if (IsKeyExist("PbocIcDataFormat"))
            {
                if (string.IsNullOrEmpty(configs["PbocIcDataFormat"]))
                    pbocFileConfig.icDataFormat = 0;
                else
                {
                    if (!Regex.IsMatch(configs["PbocIcDataFormat"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocIcDataFormatError);

                    pbocFileConfig.icDataFormat = configs["PbocIcDataFormat"] == "1" ? 1 : 0;
                }

            }

            //获取DGI的参数
            if (IsKeyExist("PbocIcRules"))
            {
                string[] icRules = ToStringArrays(configs["PbocIcRules"]);
                if (icRules != null)
                {
                    foreach (string icRule in icRules)
                    {
                        if (!Regex.IsMatch(icRule, checkRuleRegex))
                            throw new Exception(string.Format(PbocErrors.PbocIcRulesError, icRule));
                    }
                }
                pbocFileConfig.icRules = ToStringArrays(configs["PbocIcRules"]);
            }


            //获取磁条的格式(0机器码.1非机器码)
            if (IsKeyExist("PbocTrackFormat"))
            {
                if (string.IsNullOrEmpty(configs["PbocTrackFormat"]))
                    pbocFileConfig.trackFormat = 0;
                else
                {
                    if (!Regex.IsMatch(configs["PbocTrackFormat"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocTrackFormatError);
                    pbocFileConfig.trackFormat = configs["PbocTrackFormat"] == "1" ? 1 : 0;
                }

            }

            //分割磁条数据的分隔符
            if (IsKeyExist("PbocTrackSeparators"))
            {
                pbocFileConfig.trackSeparators = ToStringArrays(configs["PbocTrackSeparators"]);
            }

            ///获取磁条的规则
            if (IsKeyExist("PbocTrackRules"))
            {
                string[] tagNames = new string[3] { "track1", "track2", "track3" };
                string trackRuleRegex = @"^[^\|]*\|((\d+)\|((\d+|-\d+),(\d+|-\d+)))$";

                string[] trackRules = ToStringArrays(configs["PbocTrackRules"]);
                if (trackRules != null)
                {
                    foreach (string trackRule in trackRules)
                    {
                        string tagName=trackRule.Split('|')[0];
                        if (!tagNames.Contains(tagName) || !Regex.IsMatch(trackRule, trackRuleRegex))
                            throw new Exception(string.Format(PbocErrors.PbocTrackRulesError, trackRule));
                    }
                }
                pbocFileConfig.trackRules = ToStringArrays(configs["PbocTrackRules"]);
            }

            //获取5A数据的格式
            if (IsKeyExist("PbocFiveAFormat"))
            {
                if (string.IsNullOrEmpty(configs["PbocFiveAFormat"]))
                    pbocFileConfig.fiveAFormat = 0;
                else
                {
                    if (!Regex.IsMatch(configs["PbocFiveAFormat"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocFiveAFormatError);
                    pbocFileConfig.fiveAFormat = configs["PbocFiveAFormat"] == "1" ? 1 : 0;
                }

            }

            //获取5A的规则
            if (IsKeyExist("PbocFiveARules"))
            {
                string[] fiveARules = ToStringArrays(configs["PbocFiveARules"]);
                if (fiveARules != null)
                {
                    foreach (string fiveARule in fiveARules)
                    {
                        if (!Regex.IsMatch(fiveARule, checkRuleRegex))
                            throw new Exception(string.Format(PbocErrors.PbocFiveARulesError, fiveARule));
                    }
                }
                pbocFileConfig.fiveARules = ToStringArrays(configs["PbocFiveARules"]);
            }

            //获取银行卡号的格式
            if (IsKeyExist("PbocBankCardIdFormat"))
            {
                if (string.IsNullOrEmpty(configs["PbocBankCardIdFormat"]))
                    pbocFileConfig.bankCardIdFormat = 0;
                else
                {
                    if (!Regex.IsMatch(configs["PbocBankCardIdFormat"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocBankCardIdFormatError);
                    pbocFileConfig.bankCardIdFormat = configs["PbocBankCardIdFormat"] == "1" ? 1 : 0;
                }

            }

            //获取银行卡号的规则
            if (IsKeyExist("PbocBankCardIdRules"))
            {
                string[] bankCardIdRules = ToStringArrays(configs["PbocBankCardIdRules"]);
                if (bankCardIdRules != null)
                {
                    foreach (string bankCardIdRule in bankCardIdRules)
                    {

                        if (!Regex.IsMatch(bankCardIdRule, checkRuleRegex))
                            throw new Exception(string.Format(PbocErrors.PbocBankCardIdRulesError, bankCardIdRule));
                    }
                }
                pbocFileConfig.bankCardIdRules = ToStringArrays(configs["PbocBankCardIdRules"]);
            }

            //获取身份号的格式
            if (IsKeyExist("PbocPersonIdFormat"))
            {
                if (string.IsNullOrEmpty(configs["PbocPersonIdFormat"]))
                    pbocFileConfig.personIdFormat = 0;//默认值
                else
                {
                    if (!Regex.IsMatch(configs["PbocPersonIdFormat"], @"^[01]$"))
                        throw new Exception(PbocErrors.PbocPersonIdFormatError);
                    pbocFileConfig.personIdFormat = configs["PbocPersonIdFormat"] == "1" ? 1 : 0;
                }
            }

            //获取身份号的规则
            if (IsKeyExist("PbocPersonIdRules"))
            {
                string[] personIdRules = ToStringArrays(configs["PbocPersonIdRules"]);
                if (personIdRules != null)
                {
                    foreach (string personIdRule in personIdRules)
                    {
                        if (!Regex.IsMatch(personIdRule, checkRuleRegex))
                            throw new Exception(string.Format(PbocErrors.PbocPersonIdRulesError, personIdRule));
                    }
                }

                pbocFileConfig.personIdRules = ToStringArrays(configs["PbocPersonIdRules"]);
            }
            #endregion

            //
            ////////  检查
            //
            #region
            //检查IC数据的正则
            if (IsKeyExist("PbocIcDataCheckRegex"))
            {
                pbocFileConfig.icDataCheckRegex = configs["PbocIcDataCheckRegex"];
            }

            //检查磁条数据的正则
            if (IsKeyExist("TrackDataCheckRegex"))
            {
                pbocFileConfig.trackDataCheckRegex = configs["TrackDataCheckRegex"];
            }

            //检查银行卡号的正则
            if (IsKeyExist("PbocBankCardIdCheckRegex"))
            {
                pbocFileConfig.bankCardIdCheckRegex = configs["PbocBankCardIdCheckRegex"];
            }

            //检查身份号的正则
            if (IsKeyExist("PersonIdCheckRegex"))
            {
                pbocFileConfig.personIdCheckRegex = configs["PersonIdCheckRegex"];
            }

            #endregion

            //过滤数据项（1开始）
            #region 
            if (!IsKeyEmpty("PbocFilterItem"))
            {

                string[] items = new string[] { "bankCardId", "personId", "ssCardId" };
                string item = configs["PbocFilterItem"].Trim();

                if (!items.Contains(item))
                    throw new Exception(PbocErrors.PbocFilterItemError1);

                pbocFileConfig.filterItem = configs["PbocFilterItem"];
            }
            #endregion

            uniqueInstance=pbocFileConfig;
        }
        /// <summary>
        /// 获取配置
        /// </summary>
        /// <returns></returns>
        public static PbocFileConfig GetConfig()
        {
            if (uniqueInstance == null)
            {
                return null;
            }
            return uniqueInstance;
        }
        #endregion
    }  
}
